﻿// Singleton to keep track of the loaded workspace (which is the container for dynamic applications)
Ext.define('App.desktop.Workspace', {
    singleton: true,

    constructor: function () {

        this.callParent(arguments);

        this.user = null; // The logged in user
        this.openers = {}; // The delegates to open the children windows
        this.entities = {}; // The indexed entities metadata needed to populate the appropriate form or grid

        // To cascade the windows
        this.oldX = 50;
        this.oldY = 50;
        this.maxX = 400;
        this.maxY = 200;

        this.logOff = function () {

            Ext.Ajax.request({

                url: '/Account/LogOff',
                method: 'GET',
                success: function (response, options) {
                    window.location = '/Account/LogOn';
                }
            });
        };

        // Initializes the workspace
        this.init = function () {

            var user = Ext.decode(sessionStorage.getItem("applicationUser"));

            if (!user) {

                this.logOff();
                return;
            }

            if (!user.Applications) {

                this.showError('No applications', 'There are no applications granted for user: ' + u.UserName);
                return;
            }

            this.user = user;

            // If the user does not have a selected application, show a dialog to select it
            if (!user.SelectedApplication) {

                Ext.create('App.views.AppSelectorWindow', {
                    data: user.Applications
                }).show();

            }
            else { // Otherwise load the selected application

                this.loadApp(user.SelectedApplication.id);
            }
        };

        this.selectApp = function (appName) {

            this.user.SelectedApplication = appName;
            this.loadApp(appName);
        };

        // Loads the desktop for the given application id
        this.loadApp = function (appName) {

            var me = this;
            var mask = new Ext.LoadMask(Ext.getBody(), { msg: "Please wait..." });
            mask.show();

            Ext.Ajax.request({
                url: '/App/SelectApplication',
                method: 'POST',
                params: {
                    appName: appName
                },
                success: function (response, options) {

                    mask.hide();

                    var d = Ext.decode(response.responseText);

                    if (d.success === true) {

                        // Index the metadata about the entities
                        Ext.each(d.data.Domain.Entities, function (e, i) {

                            me.entities[e.FullName] = e;
                        });

                        Ext.application.Desktop = Ext.create('App.desktop.Desktop', {
                            data: d.data
                        });

                    }
                    else {

                        if (d.msg) {

                            if (d.msg == 'Session expired') { // Log out the user if the session expired

                                me.logOff();
                                return;
                            }

                            me.showError('Select application failed', d.msg);
                        }
                    }
                },

                failure: function () {
                    mask.hide();
                }
            });
        }

        // Converts the fields of the object to an array
        this.toArray = function (o) {

            var a = [];

            for (var k in o) {

                a.push({
                    Name: k,
                    Value: o[k]
                });
            }

            return a;
        };

        // Shows the error message
        this.showError = function (title, msg) {

            Ext.MessageBox.show({
                title: title,
                msg: msg,
                width: 300,
                buttons: Ext.MessageBox.OK
            });
        };

        // Converts the type from enumeration to string
        this.getType = function (type) {

            switch (type) {
                case 1: return 'string';
                case 2: return 'int';
                case 3: return 'float';
                case 4: return 'boolean';
                case 5: return 'date';
                case 6: return 'complex';
                case 7: return 'collection';
                default: return 'auto';
            }
        };

        this.openDetailWindow = function (owner, config) {

            var me = this;

            if (!owner) {

                owner = Ext.create('App.desktop.DetailWindow', {
                    x: me.oldX,
                    y: me.oldY,
                    operation: config.operation,
                    entity: config.entity,
                    child: config.child,
                    attribute: config.attribute,
                    identifiers: config.identifiers,
                    callback: config.callback
                });

                me.updateXY();
            }
            else {

                owner.refresh(config.operation, config.identifiers, config.callback);
            }

            owner.show();
            owner.focus();
        };

        this.openGridWindow = function (owner, config) {

            var me = this;

            if (!owner) {

                owner = Ext.create('App.desktop.GridWindow', {
                    x: me.oldX,
                    y: me.oldY,
                    entity: config.entity,
                    child: config.child,
                    attribute: config.attribute,
                    identifiers: config.identifiers
                });

                me.updateXY();

            } else {

                owner.loadGrid();
            }

            owner.show();
            owner.focus();
        };

        // Creates the window openers for the complex and collection attributes of the entity
        this.createOpeners = function (entity) {

            var me = this;
            var count = entity.Attributes.length;

            for (var i = 0; i < count; ++i) {

                var attribute = entity.Attributes[i];
                var type = me.getType(attribute.Category);
                var key = entity.FullName + '.' + attribute.Name;

                switch (type) {

                    case 'complex':
                        {
                            if (me.openers[key]) {
                                return; // The openers were already created
                            }

                            (function (a) {

                                me.openers[key] =
                                {
                                    window: null,
                                    openWindow: function (parentId) {

                                        me.openDetailWindow(this.window, {
                                            entity: entity,
                                            child: me.entities[a.TypeName], // Pass the entity of the attribute
                                            attribute: a,
                                            identifiers: parentId
                                        });
                                    }
                                };
                            })(attribute);
                        }
                        break;
                    case 'collection':
                        {
                            if (me.openers[key]) {
                                return; // The openers were already created
                            }

                            (function (a) {

                                me.openers[key] =
                                {
                                    window: null,
                                    openWindow: function (parentId) {

                                        me.openGridWindow(this.window, {
                                            entity: entity,
                                            child: me.entities[a.TypeName], // Pass the entity of the attribute
                                            attribute: a,
                                            identifiers: parentId
                                        });
                                    }
                                };
                            })(attribute);
                        }
                        break;
                }

            }
        };

        // Opens a child window using the opener
        this.openWindow = function (entityName, attributeName, parentId) {

            var me = this;
            var key = entityName + '.' + attributeName;
            var opener = me.openers[key];

            parentId = Ext.encode(parentId);
            parentId = parentId.replace(/["']{1}/gi, "");

            opener.openWindow(parentId);
        };

        // Updates the x and y parameters of the next window to be open
        this.updateXY = function () {

            var me = this;

            me.oldX += 20;

            if (me.oldX > me.maxX) {
                me.oldX = 50;
            }

            me.oldY += 20;

            if (me.oldY > me.maxY) {
                me.oldY = 50;
            }
        };

        //        this.findAttribute = function (entity, attributeName) {

        //            var attributes = entity.Attributes;
        //            var count = attributes.length;

        //            for (var i = 0; i < count; ++i) {

        //                var attribute = attributes[i];

        //                if (attribute.Name == attributeName) {
        //                    return attribute;
        //                }
        //            }
        //        };
    }
});